package com.mmc.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.mmc.common.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletResponse;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 验证码控制器
 *
 * @author kunfe
 * @since 2024-01-01
 */
@Tag(name = "验证码管理", description = "验证码生成和验证")
@RestController
@RequestMapping("/api/captcha")
@RequiredArgsConstructor
@Slf4j
public class CaptchaController {

    private final DefaultKaptcha defaultKaptcha;
    private final RedisTemplate<String, String> redisTemplate;
    
    private static final String CAPTCHA_KEY_PREFIX = "captcha:";
    private static final int CAPTCHA_EXPIRE_MINUTES = 5;

    @Operation(summary = "生成图形验证码")
    @SaIgnore
    @GetMapping("/get")
    public Result<Object> getCaptcha() {
        try {
            // 生成验证码文字
            String captchaText = defaultKaptcha.createText();
            // 生成验证码图片
            BufferedImage captchaImage = defaultKaptcha.createImage(captchaText);
            
            // 生成唯一的验证码ID
            String captchaId = UUID.randomUUID().toString();
            
            // 将验证码文字存入Redis，设置5分钟过期
            redisTemplate.opsForValue().set(
                CAPTCHA_KEY_PREFIX + captchaId, 
                captchaText.toLowerCase(), 
                CAPTCHA_EXPIRE_MINUTES, 
                TimeUnit.MINUTES
            );
            
            // 将图片转换为Base64
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(captchaImage, "jpg", baos);
            String base64Image = Base64.getEncoder().encodeToString(baos.toByteArray());
            
            Map<String, Object> result = new HashMap<>();
            result.put("captchaEnabled", true);
            result.put("captchaId", captchaId);
            result.put("captchaImage", "data:image/jpg;base64," + base64Image);
            
            log.info("生成验证码成功，ID: {}, 内容: {}", captchaId, captchaText);
            return Result.ok(result);
        } catch (Exception e) {
            log.error("生成验证码失败", e);
            Map<String, Object> result = new HashMap<>();
            result.put("captchaEnabled", false);
            result.put("message", "验证码生成失败");
            return Result.fail("验证码生成失败");
        }
    }

    @Operation(summary = "验证图形验证码")
    @SaIgnore
    @PostMapping("/check")
    public Result<Boolean> checkCaptcha(@RequestBody CaptchaRequest request) {
        try {
            if (request.getCaptchaId() == null || request.getCaptchaCode() == null) {
                return Result.fail("验证码参数不能为空");
            }
            
            // 从Redis获取正确的验证码
            String correctCode = redisTemplate.opsForValue().get(CAPTCHA_KEY_PREFIX + request.getCaptchaId());
            
            if (correctCode == null) {
                return Result.fail("验证码已过期");
            }
            
            // 验证码验证（不区分大小写）
            boolean isValid = correctCode.equalsIgnoreCase(request.getCaptchaCode().trim());
            
            if (isValid) {
                // 验证成功后删除验证码，防止重复使用
                redisTemplate.delete(CAPTCHA_KEY_PREFIX + request.getCaptchaId());
                log.info("验证码验证成功，ID: {}", request.getCaptchaId());
                return Result.ok(true);
            } else {
                log.warn("验证码验证失败，ID: {}, 输入: {}, 正确: {}", 
                    request.getCaptchaId(), request.getCaptchaCode(), correctCode);
                return Result.fail("验证码错误");
            }
        } catch (Exception e) {
            log.error("验证验证码失败", e);
            return Result.fail("验证码验证失败");
        }
    }

    /**
     * 验证码请求参数
     */
    public static class CaptchaRequest {
        private String captchaId;
        private String captchaCode;

        public String getCaptchaId() { return captchaId; }
        public void setCaptchaId(String captchaId) { this.captchaId = captchaId; }
        public String getCaptchaCode() { return captchaCode; }
        public void setCaptchaCode(String captchaCode) { this.captchaCode = captchaCode; }
    }
} 